feat(statics): add Pearl to statics#9347
Conversation
d507bc6 to
0f546d8
Compare
e940684 to
563cbd8
Compare
96342d0 to
8317443
Compare
|
@claude review |
|
Claude finished @manojkumar138's task —— View job Code Review - Pearl (PEARL) Integration✅ Completed Reviews1. Base Configuration (
2. Network Classes (
3. UTXO Coin Definitions (
4. UTXO-lib Network Configuration (
5. Test Fixtures and Validation ✅
🎯 Key Validation Points ✅
📊 Review SummaryStatus: ✅ APPROVED The Pearl (PEARL) cryptocurrency integration is well-implemented and complete. The implementation properly follows BitGo's established patterns and includes:
The integration correctly implements Pearl as a Taproot-enabled UTXO coin with bech32m addressing (prl/tprl prefixes) and includes all necessary features for BitGo wallet functionality. No issues identified. Ready for merge. |
There was a problem hiding this comment.
Pull request overview
This PR introduces Pearl (pearl / tpearl) as a recognized UTXO network across BitGoJS’ statics + UTXO stack (statics, utxo-lib, utxo-core, utxo-bin, abstract-utxo tests), including Taproot-only wallet script-type enforcement to match @bitgo/wasm-utxo behavior.
Changes:
- Adds Pearl network definitions (mainnet/testnet) and detection helpers in
@bitgo/utxo-lib, including Taproot-only script-type gating inoutputScripts.isSupportedScriptType. - Registers Pearl coin metadata in
@bitgo/statics(family/asset/network/utxo coin entries + expectedColdFeatures). - Updates dust threshold logic, CLI network parsing order, tests, and extensive address/PSBT fixtures; bumps
@bitgo/wasm-utxoto^4.27.0across affected modules.
Reviewed changes
Copilot reviewed 92 out of 93 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Bumps @bitgo/wasm-utxo and updates transitive lock entries. |
| modules/utxo-staking/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-ord/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-descriptors/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-core/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-bin/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/abstract-utxo/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/statics/src/base.ts | Adds CoinFamily.PEARL and UnderlyingAsset.PEARL. |
| modules/statics/src/networks.ts | Adds Pearl mainnet/testnet network objects to Networks. |
| modules/statics/src/utxo.ts | Adds pearl/tpearl UTXO coin entries and feature set. |
| modules/statics/test/unit/fixtures/expectedColdFeatures.ts | Adds pearl/tpearl to expected cold-feature fixtures. |
| modules/utxo-lib/src/networks.ts | Adds pearl/tpearl networks, NetworkName union updates, and helpers (isPearl, segwit/taproot support). |
| modules/utxo-lib/src/bitgo/outputScripts.ts | Enforces Taproot-only script type support for Pearl via isSupportedScriptType. |
| modules/utxo-lib/src/bitgo/transaction.ts | Enables transaction/PSBT factory support for networks.pearl. |
| modules/utxo-core/src/dustThreshold.ts | Treats Pearl like BTC-group for dust relay limit and spend size. |
| modules/utxo-core/test/dustThreshold.ts | Adds Pearl expected dust-threshold test vectors. |
| modules/utxo-bin/src/args/parseNetwork.ts | Adds Pearl to the CLI network ordering (mainnet group). |
| modules/utxo-lib/test/networks.ts | Extends network property-sharing groups and feature expectation table for Pearl. |
| modules/utxo-lib/test/bitgo/outputScripts.ts | Adds expected script types for Pearl (p2tr, p2trMusig2). |
| modules/utxo-lib/test/integration_local_rpc/parse.ts | Skips Pearl in regtest fixture suite until generator supports it. |
| modules/utxo-lib/test/fixtures_thirdparty/parse.ts | Excludes Pearl from third-party fixture parsing. |
| modules/utxo-lib/test/fixtures_thirdparty/download.ts | Excludes Pearl from third-party fixture downloads. |
| modules/utxo-lib/test/bitgo/psbt/Psbt.ts | Skips a p2ms-only extraction suite for Pearl. |
| modules/utxo-lib/test/bitgo/psbt/SignVerifyLegacy.ts | Skips legacy PSBT signing suite for taproot-only Pearl. |
| modules/utxo-lib/test/address/fixtures/pearl.json | Adds Pearl address vectors. |
| modules/utxo-lib/test/address/fixtures/tpearl.json | Adds Pearl testnet address vectors. |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt.pearl.unsigned.json | Adds Pearl PSBT fixture (unsigned). |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt.pearl.halfsigned.json | Adds Pearl PSBT fixture (half-signed). |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt-lite.pearl.unsigned.json | Adds Pearl “lite” PSBT fixture (unsigned). |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt-lite.pearl.halfsigned.json | Adds Pearl “lite” PSBT fixture (half-signed). |
| modules/abstract-utxo/test/unit/coins.ts | Documents Pearl networks as lacking coin classes yet (undefined). |
| modules/abstract-utxo/test/unit/util/utxoCoins.ts | Adds hasUtxoCoinForNetwork predicate for tests. |
| modules/abstract-utxo/test/unit/transaction/fixedScript/parsePsbt.ts | Filters AcidTest suite by hasUtxoCoinForNetwork. |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2pkh_default_1LCVrCgbT26Ui1QyrhaGvvhrkVdDRAXxtt.txt | Adds Pearl formatAddress fixture (p2pkh). |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2wkh_default_prl1q62tshlryz9lrjlw9edaf4l5l3v3deg03gw29k2.txt | Adds Pearl formatAddress fixture (p2wkh). |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2tr_default_prl1p8gv9m64s539mycj4m29wu8thy5n3y6u36xs58wq3yezrmqygwfns2yff0j.txt | Adds Pearl formatAddress fixture (p2tr). |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2trMusig2_default_prl1p5xqvqger0zdpcq6s3jznfz352exhk356p9hml6c69matmggrve9sq7apju.txt | Adds Pearl formatAddress fixture (p2trMusig2). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2pkh_default_mziT9FmaG3XjV7tbaGYekqvBcVDvGnY3EZ.txt | Adds tpearl formatAddress fixture (p2pkh). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2wkh_default_tprl1q62tshlryz9lrjlw9edaf4l5l3v3deg03lufv9q.txt | Adds tpearl formatAddress fixture (p2wkh). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2tr_default_tprl1p8gv9m64s539mycj4m29wu8thy5n3y6u36xs58wq3yezrmqygwfnsptdhs8.txt | Adds tpearl formatAddress fixture (p2tr). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2trMusig2_default_tprl1p5xqvqger0zdpcq6s3jznfz352exhk356p9hml6c69matmggrve9st3eldf.txt | Adds tpearl formatAddress fixture (p2trMusig2). |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2pkh_default_1LCVrCgbT26Ui1QyrhaGvvhrkVdDRAXxtt.txt | Updates network candidate list to include Pearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2pkh_default_1LCVrCgbT26Ui1QyrhaGvvhrkVdDRAXxtt.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2sh_default_361UWADXqgPsdf8L5Jga6GNPauMuBtT1eW.txt | Updates network candidate list to include Pearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2sh_default_361UWADXqgPsdf8L5Jga6GNPauMuBtT1eW.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2shP2wsh_default_33qtbAwm4ooBtMQenssbqDE1J4gSMMBRnb.txt | Updates network candidate list to include Pearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2shP2wsh_default_33qtbAwm4ooBtMQenssbqDE1J4gSMMBRnb.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2tr_default_bc1p8gv9m64s539mycj4m29wu8thy5n3y6u36xs58wq3yezrmqygwfnsjhucex.all.txt | Adds Pearl/tpearl conversions for taproot addresses. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2trMusig2_default_bc1p5xqvqger0zdpcq6s3jznfz352exhk356p9hml6c69matmggrve9scdgsyg.all.txt | Adds Pearl/tpearl conversions for taproot-musig2 addresses. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2wkh_default_bc1q62tshlryz9lrjlw9edaf4l5l3v3deg034uw28c.all.txt | Adds Pearl/tpearl conversions for segwit v0 addresses. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2wsh_default_bc1qeu6xmet5wqslj2w0wac0hx5gj6dupmp869cajrkt3kw6ud3kkecsdzf7hn.all.txt | Adds Pearl/tpearl conversions for segwit v0 scripts. |
| modules/utxo-bin/test/fixtures/formatAddress/testnet_p2pkh_default_mziT9FmaG3XjV7tbaGYekqvBcVDvGnY3EZ.txt | Updates candidate network lists to include tpearl where prefixes collide. |
| modules/utxo-bin/test/fixtures/formatAddress/testnet_p2sh*_default_2M*.txt | Updates candidate network lists to include tpearl where prefixes collide. |
| modules/utxo-bin/test/fixtures/formatAddress/cash_*.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/sv_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bch_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/btg_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/doge_* | Updates network candidate lists to include tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/ecash_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/litecoinTest_* | Updates network candidate lists to include tpearl. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const PEARL_FEATURES = [ | ||
| ...UtxoCoin.DEFAULT_FEATURES, | ||
| CoinFeature.MULTISIG, | ||
| CoinFeature.BULK_TRANSACTION, | ||
| CoinFeature.DISTRIBUTED_CUSTODY, | ||
| ]; |
OttoAllmendinger
left a comment
There was a problem hiding this comment.
remove utxo-lib changes
8317443 to
8a68ca6
Compare
Define Pearl (PEARL/TPEARL) coin identity in @bitgo/statics: CoinFamily, UnderlyingAsset, the Pearl/PearlTestnet network classes and the pearl and tpearl coin entries. Pearl is a taproot-only UTXO chain (btcd fork) using BIP-340 Schnorr signatures and BIP-341 script-path spending. It is backed by @bitgo/wasm-utxo, which has carried pearl and tpearl in CoinName since 4.27.0. No @bitgo/utxo-lib network is registered. Pearl is intended to be served through the wasm-utxo path, matching the wasm-only profile already used by ims-utxo, so utxolibName names the wasm CoinName rather than a utxo-lib network entry. TICKET: CECHO-1780 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
8a68ca6 to
6651eb1
Compare
|
@OttoAllmendinger that all matches what's here now — this PR touches
So nothing to undo. The Scoping the follow-up to your last point — basic fixed-script wallet surface in
No descriptors, no ordinals, no I'll hold off until this one merges so the statics entry exists first — shout if you'd rather I stack it on this branch now. |
|
@OttoAllmendinger dropped the utxo-lib changes — PR is now statics-only: 4 files, 48 insertions, rebased onto current master. Blockers: none for this PRI checked this empirically rather than by inspection — stripped the utxo-lib changes and ran the full chain:
All build clean. Nothing cross-checks statics' Everything else in the previous revision existed only to support the utxo-lib network, so it all went with it: the One thing to be aware ofNot a blocker here, but it's the thing that bites later. const network = utxolib.networks[coin.network.utxolibName as utxolib.NetworkName];in both It isn't reached today — no SDK coin class exists for Pearl, and the sdk-core tests covering those two functions use a hardcoded list ( Also worth flagging since it's unavoidable rather than a choice: This looks tractable end-to-endWhile tracing the above I checked how coupled So a wasm-only Pearl coin class looks feasible without reintroducing utxo-lib — the work being |
|
@claude review |
|
Claude encountered an error —— View job Code Review - Pearl (PEARL) Integration
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
modules/statics/src/utxo.ts:151
PEARL_FEATURESrepeatsCoinFeature.MULTISIG, which is already included inUtxoCoin.DEFAULT_FEATURES. This can leave duplicate entries in the coin'sfeaturesarray, which is easy to miss and can cause brittle equality/serialization behavior downstream.
const PEARL_FEATURES = [
...UtxoCoin.DEFAULT_FEATURES,
CoinFeature.MULTISIG,
CoinFeature.BULK_TRANSACTION,
CoinFeature.DISTRIBUTED_CUSTODY,
];
modules/statics/src/networks.ts:1445
- Same as mainnet: since Pearl testnet is wasm-only and not present in
@bitgo/utxo-libnetworks, it’s worth documenting thatutxolibNamehere refers to the wasm coin name, not an actual utxo-lib network key.
name = 'PearlTestnet';
family = CoinFamily.PEARL;
utxolibName = 'tpearl';
explorerUrl = undefined;
| name = 'Pearl'; | ||
| family = CoinFamily.PEARL; | ||
| utxolibName = 'pearl'; | ||
| explorerUrl = undefined; |

Summary
Defines Pearl's coin identity in
@bitgo/statics. Noutxo-libchanges — Pearl is intended to be served through the@bitgo/wasm-utxopath, matching the wasm-only profile already used by ims-utxo.4 files, 48 insertions.
Chain Type
UTXO — Taproot-only (BIP-340 Schnorr, BIP-341 script-path with a NUMS internal key). Pearl is a btcd fork.
@bitgo/wasm-utxois authoritative on script-type support and restricts Pearl to Taproot:Coin Codes & Tickers
pearlPEARLtpearlTPEARLNames match
@bitgo/wasm-utxo(coinNames: [..., "pearl", "tpearl"]) and indexer-utxo (CoinSymbol.pearl/CoinSymbol.tpearl).Network Parameters
prltprlm/86'/808276'/0'm/86'/1'/0'Changes
src/base.tsCoinFamily.PEARL,UnderlyingAsset.PEARLsrc/networks.tsPearl/PearlTestnetclasses +Networks.main/Networks.testentriessrc/utxo.tspearl/tpearlcoin entries, explicitPEARL/TPEARLsuffixes,MULTISIG+BULK_TRANSACTION+DISTRIBUTED_CUSTODYtest/unit/fixtures/expectedColdFeatures.tsjustMultiSigOn
utxolibNameUtxoNetworkrequires autxolibName: string, so the classes set'pearl'/'tpearl'— the wasmCoinNames. With no utxo-lib network registered, these do not resolve to autxolib.networksentry. That is intentional under the wasm-only approach, and the one structural consequence is noted below.Verification
staticsutxo-libutxo-coreabstract-utxoutxo-binAll build clean (
statics,utxo-lib,utxo-core,abstract-utxo,utxo-bin,sdk-core); prettier clean. Rebased onto current master.Known consequence of the wasm-only approach
Nothing in this PR is blocked, but for the record:
sdk-core'sabstractUtxoCoinUtil.tsresolves statics'utxolibNameinto a utxo-lib network —— in both
getUtxoCoinScriptTypes2Of3()andgetUtxoCoinScriptTypesForWalletType(). For Pearl that yieldsundefinedand then throwsTypeError: invalid network.Not reachable today: no SDK coin class exists for Pearl, and the sdk-core tests covering those functions use a hardcoded coin list (
btc,ltc,doge) rather than enumerating statics. It becomes reachable when the coin class lands, so those two functions need a wasm-backed path (or a Pearl guard) before Pearl is wired into wallet/address flows.The good news for that follow-up:
abstract-utxois already almost entirely wasm-backed — 37 files import@bitgo/wasm-utxo, and the only 3 mentioningutxolibare a deprecation comment inabstractUtxoCoin.ts("will be removed when we drop support for utxolib"), a comment inunspent.ts, and BTC-specificinscriptionBuilder.ts. Coin classes carry aname, not aNetwork, so a wasm-only Pearl coin class looks feasible without reintroducing utxo-lib.Dependencies
Already merged upstream:
Related
🤖 Generated with Claude Code